package utility

import (
	"fmt"
	. "gini2p/config"
	"gini2p/logger"
	"math/rand"
	"net/url"
	"os"
	"runtime/debug"
	"strconv"
	"strings"
	"time"

	"encoding/json"

	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
)

//GenerateLogID 生成logID
func GenerateLogID() string {
	//创建伪随机资源
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	return strconv.FormatInt(time.Now().UnixNano(), 10) + fmt.Sprintf("%d", r.Intn(10000))
}

//PacnicStack 崩溃日志
func PacnicStack() {
	if err := recover(); err != nil {
		str := string(debug.Stack()) + "\n--------------------------------------\n"
		str += fmt.Sprintln(err) + "\n"
		file, err := os.OpenFile(Log.Path+"/crash.log", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
		if err != nil {
			fmt.Println(err.Error())
			return
		}
		defer file.Close()
		_, err = file.WriteString(str)
		if err != nil {
			logger.Error(err.Error())
			return
		}
		fmt.Println("stack := ", str)
		return
	}
}

func RenewSession(c *gin.Context, token string, id int64) {
	session := sessions.Default(c)
	sessionData := SessionData{
		Uid:         id,
		AccessToken: token,
		LastTime:    time.Now(),
		IpAddress:   c.ClientIP(),
	}
	data, err := json.Marshal(sessionData)
	if err != nil {
		logger.Error("app", fmt.Sprint("储存session出错:", err))
	}
	logger.Info("app", fmt.Sprint("登录成功:", string(data)))
	session.Set("token", data)
	session.Save()
	return
}

//格式化日志记录
func FormatLog(c *gin.Context, msg string) string {
	session := sessions.Default(c)
	tokenData := session.Get("token")
	var sessionData SessionData
	err := json.Unmarshal(tokenData.([]byte), &sessionData)
	if err != nil {
		logger.Error("app", "解json字符串出错:", err)
	}
	return fmt.Sprint("************** Client : ", c.Request.RemoteAddr, " [", c.Request.Method, "] ", c.Request.URL.Path, "  from : [", c.Request.PostForm, "], uid: [", sessionData.Uid, "], *****************", msg)
}

//计算分页相关信息
func MakePageInformation(total, page, pageSize int64) (totalPage, offset int64) {
	if pageSize == 0 {
		pageSize = PageSize
	}
	if page == 0 {
		page = 1
	}
	totalPage = (total + pageSize - 1) / pageSize
	offset = (page - 1) * pageSize
	return totalPage, offset
}

func FormatSearchParams(c *gin.Context, searchName string) string {
	rawQuery := c.Request.URL.RawQuery
	getParams, _ := url.ParseQuery(rawQuery)

	searchValues := map[string]string{}

	for _, v := range SearchParams[searchName] {
		if val, ok := getParams[v]; ok {
			searchValues[v] = val[0]
		}
	}

	where := " and "
	for k, v := range searchValues {
		where += k + " = " + v + " and "
	}

	if strings.HasSuffix(where, " and ") {
		where = where[0 : len(where)-4]
	}

	return where
}
